package com.sign.utils.sm2;

import lombok.Builder;
import lombok.Data;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.oer.its.EccP256CurvePoint;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;

import java.io.FileWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;

public class P10Test {

    public static CertificateRequest genCertificateRequest() {
        try {

            String signalg = "SHA256WithRSA";
            int alglength = 2048;
            String keyAlg = "RSA";

            String o = "00276DF";
            String ou = "SN_TEST_008";
            String cn = o + "_" + ou;

            X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);
            x500NameBld.addRDN(BCStyle.CN, cn);
            x500NameBld.addRDN(BCStyle.C, "China");
            x500NameBld.addRDN(BCStyle.ST, "Guangdong");
            x500NameBld.addRDN(BCStyle.L, "Tianhe");
            x500NameBld.addRDN(BCStyle.O, o);
            x500NameBld.addRDN(BCStyle.OU, ou);
            x500NameBld.addRDN(BCStyle.EmailAddress, "feedback@bouncycastle.org");
            X500Name subject = x500NameBld.build();


          /*  x500NameBld.addRDN(BCStyle.CN, "userName or CompName"); //个人，企业用户名
            x500NameBld.addRDN(BCStyle.C, "CN");  //国家
            x500NameBld.addRDN(BCStyle.O, "39dian blog"); //机构名称
            x500NameBld.addRDN(BCStyle.ST, "shanghai");  //省
            x500NameBld.addRDN(BCStyle.L, "shanghai");  //市
            x500NameBld.addRDN(BCStyle.E, "admin@39dian.com"); //邮箱*/

            //秘钥对改为自己的，这里使用自动生成
          /*  KeyPairGenerator keyGen = KeyPairGenerator.getInstance(keyAlg);
            keyGen.initialize(alglength);
            KeyPair kp = keyGen.generateKeyPair();*/


            //生成公私钥对
            String[] keys = KeyUtils.generateSmKey();
            PublicKey publicKey = KeyUtils.createPublicKey(keys[0]);
            PrivateKey privateKey = KeyUtils.createPrivateKey(keys[1]);

            PKCS10CertificationRequestBuilder builder = new PKCS10CertificationRequestBuilder(subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));

            JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(SignAlg.SIGN_ALGO_SM3WITHSM2);
            ContentSigner contentSigner = jcaContentSignerBuilder.setProvider(Sm2Util.BC).build(privateKey);
            PKCS10CertificationRequest pkcs10 = builder.build(contentSigner);

          /*  JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(new FileWriter("cert/test.csr"));
            jcaPEMWriter.writeObject(pkcs10);
            jcaPEMWriter.close();*/

            String p10Str = Base64.getMimeEncoder().encodeToString(pkcs10.getEncoded());
            String publicKeyStr = Base64.getMimeEncoder().encodeToString(publicKey.getEncoded());
            String privateKeyStr = Base64.getMimeEncoder().encodeToString(privateKey.getEncoded());
            return CertificateRequest.builder()
                    .p10Str(p10Str)
                    .publicKeyStr(publicKeyStr)
                    .privateKeyStr(privateKeyStr)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Builder
    @Data
    static class CertificateRequest {
        private String publicKeyStr;
        private String privateKeyStr;
        private String p10Str;
    }

    public static void main(String[] args) {
        CertificateRequest certificateRequest = genCertificateRequest();
        System.out.println("私钥：\n"+certificateRequest.getPrivateKeyStr());
        System.out.println("公钥："+certificateRequest.getPublicKeyStr());
        System.out.println("csr \n"+certificateRequest.getP10Str());
    }
}
